package com.study.goal.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.study.goal.domain.PlanExecutionLog;
import com.study.goal.domain.PlanOccurrence;
import com.study.goal.mapper.PlanExecutionLogMapper;
import com.study.goal.mapper.PlanOccurrenceMapper;
import com.study.goal.service.IPlanExecutionLogService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Service
public class IPlanExecutionLogServiceImpl implements IPlanExecutionLogService {

    private final PlanOccurrenceMapper planOccurrenceMapper;

    private final PlanExecutionLogMapper planExecutionLogMapper;

    @Transactional
    @Override
    public Boolean startCheckIn(Long studentId, Long planOccurrenceId, String remark) {

        //根据信息查看是否已经完成第一次打卡
        PlanExecutionLog executionLog = planExecutionLogMapper.selectOne(new LambdaQueryWrapper<PlanExecutionLog>()
                .eq(PlanExecutionLog::getStudentId, studentId)
                .eq(PlanExecutionLog::getPlanOccurrenceId, planOccurrenceId));

        if (executionLog != null) {
            throw new RuntimeException("该任务开始打卡进行，不能重复开始打卡，请完成任务后在进行打卡上传");
        }

        PlanExecutionLog planExecutionLog = new PlanExecutionLog();
        planExecutionLog.setStudentId(studentId);
        planExecutionLog.setPlanOccurrenceId(planOccurrenceId);
        planExecutionLog.setStatus("STARTED");
        planExecutionLog.setRemark(remark);
        planExecutionLog.setCreateTime(LocalDateTime.now());
        planExecutionLog.setStartTime(LocalDateTime.now());
        return planExecutionLogMapper.insert(planExecutionLog) > 0;
    }

    @Override
    public Boolean completeCheckIn(Long studentId, Long planOccurrenceId, String remark, String evidenceUrl) {
        //根据信息查看是否已经完成第一次打卡
        PlanExecutionLog executionLog = planExecutionLogMapper.selectOne(new LambdaQueryWrapper<PlanExecutionLog>()
                .eq(PlanExecutionLog::getStudentId, studentId)
                .eq(PlanExecutionLog::getPlanOccurrenceId, planOccurrenceId));

        if (executionLog == null) {
            throw new RuntimeException("任务未开始，不能直接完成打卡");
        }

        if (executionLog.getStatus().equals("COMPLETED")) {
            throw new RuntimeException("任务已经完成，请勿重复完成");
        }

        executionLog.setStatus("COMPLETED");
        executionLog.setRemark(remark);
        executionLog.setEvidenceUrl(evidenceUrl);
        executionLog.setCompletionTime(LocalDateTime.now());
        executionLog.setUpdateTime(LocalDateTime.now());
        return planExecutionLogMapper.updateById(executionLog) > 0;

    }

    @Override
    public List<PlanExecutionLog> getTodayTasks(Long studentId, LocalDate date) {
        List<PlanOccurrence> occurrenceList = planOccurrenceMapper.selectList(new LambdaQueryWrapper<PlanOccurrence>()
                .eq(PlanOccurrence::getAssignmentId, studentId)
                .eq(PlanOccurrence::getScheduledAt, date));

        if (occurrenceList.isEmpty()) {
            return new ArrayList<>();
        }

        List<Long> occurrenceIds = occurrenceList.stream()
                .map(PlanOccurrence::getId)
                .collect(Collectors.toList());

        return planExecutionLogMapper.selectList(new LambdaQueryWrapper<PlanExecutionLog>()
                .eq(PlanExecutionLog::getStudentId, studentId)
                .in(PlanExecutionLog::getPlanOccurrenceId, occurrenceIds));

    }

    @Override
    public Map<String, Object> getExecutionStats(Long goalAssignmentId, Long studentId) {

        Map<String, Object> result = new HashMap<>();

        List<PlanOccurrence> occurrenceList = planOccurrenceMapper.selectList(new QueryWrapper<PlanOccurrence>()
                .eq("assignment_id", goalAssignmentId));

        if (occurrenceList.isEmpty()) {

            result.put("total", 0);
            result.put("completed", 0);
            result.put("completionRate", 0);
            return result;
        }

        List<Long> occurrenceIds = occurrenceList.stream()
                .map(PlanOccurrence::getId)
                .collect(Collectors.toList());

        int total = planExecutionLogMapper.selectCount(new QueryWrapper<PlanExecutionLog>()
                .eq("student_id", studentId)
                .in("plan_occurrence_id", occurrenceIds)).intValue();

        int completed = planExecutionLogMapper.selectCount(new QueryWrapper<PlanExecutionLog>()
                .eq("student_id", studentId)
                .eq("status", "COMPLETED")
                .in("plan_occurrence_id", occurrenceIds)).intValue();

        result.put("total", total);
        result.put("completed", completed);
        result.put("completionRate", completed * 1.0 / total);

        return result;
    }
}
